﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using BLL.DataContextClasses;

namespace BLL.BusinessClasses
{
    public abstract class UsuarioUniversitario : BLL.BusinessClasses.UsuarioAplicacion
    {
        #region Campos
        protected string matricula;
        protected string estado;
        protected string primerNombre;
        protected string segundoNombre;
        protected string primerApellido;
        protected string segundoApellido;
        protected DateTime fechaNacimiento;
        protected int edad;
        protected string sexo;
        protected int experienciaLaboral;
        protected string detalleExperienciaLaboral;
        protected string intereses;
        protected bool siVehiculoPropio;
        protected bool siBuscaTiempoCompleto;
        protected string foto;
        protected List<Aplicacion> aplicaciones;
        protected List<Contacto> contactos;
        protected List<Habilidad> habilidades;
        #endregion

        #region Propiedades
        public string Matricula
        {
            get { return this.matricula; }
        }
        public string Estado
        {
            get { return this.estado; }
            set { this.estado = value.Trim(); }
        }
        public string PrimerNombre // Esta propiedad deberia ser ReadOnly
        {
            get { return this.primerNombre; }
            set { this.primerNombre = value.Trim(); }
        }
        public string SegundoNombre // Esta propiedad deberia ser ReadOnly
        {
            get { return this.segundoNombre; }
            set { this.segundoNombre = value.Trim(); }
        }
        public string PrimerApellido // Esta propiedad deberia ser ReadOnly
        {
            get { return this.primerApellido; }
            set { this.primerApellido = value.Trim(); }
        }
        public string SegundoApellido // Esta propiedad deberia ser ReadOnly
        {
            get { return this.segundoApellido; }
            set { this.segundoApellido = value.Trim(); }
        }
        public string Nombres
        {
            get { return (this.primerNombre + " " + this.segundoNombre).Trim(); }
        }
        public string Apellidos
        {
            get { return (this.primerApellido + " " + this.segundoApellido).Trim(); }
        }
        public string NombreCompleto
        {
            get { return (this.Nombres + " " + this.Apellidos).Trim(); }
        }
        public DateTime FechaNacimiento
        {
            get { return this.fechaNacimiento; }
        }
        public int Edad
        {
            get { return this.edad; }
        }
        public string Sexo
        {
            get { return this.sexo; }
        }
        public int AñosDeExperienciaLaboral
        {
            get { return this.experienciaLaboral; }
            set { this.experienciaLaboral = value; }
        }
        public string DetalleExperienciaLaboral
        {
            get { return this.detalleExperienciaLaboral; }
            set { this.detalleExperienciaLaboral = value.Trim(); }
        }
        public string Intereses
        {
            get { return this.intereses; }
            set { this.intereses = value.Trim(); }
        }
        public bool SiVehiculoPropio
        {
            get { return this.siVehiculoPropio; }
            set { this.siVehiculoPropio = value; }
        }
        public bool SiBuscaTiempoCompleto
        {
            get { return this.siBuscaTiempoCompleto; }
            set { this.siBuscaTiempoCompleto = value; }
        }
        public string Foto
        {
            get { return this.foto; }
            set { this.foto = value; }
        }
        public abstract List<Aplicacion> Aplicaciones
        {
            get;
            set;
        }        
        public abstract List<Habilidad> Habilidades
        {
            get;
            set;
        }        
        public abstract List<Contacto> Contactos
        {
            get;
            set;
        }        
        #endregion         
 
        #region // Metodos
        public static UsuarioUniversitario GetAplicanteByAplicacionID(int AplicacionID)
        {
            DataClassesDataContext DB = new DataClassesDataContext();
            UsuarioUniversitario Aplicante = null;

            try
            {
                DataContextClasses.Aplicacione Apl = (from a in DB.Aplicaciones
                                                      where a.ID == AplicacionID
                                                      select a).First();

                if (Apl.ID_Egresado.HasValue)
                {
                    Aplicante = new UsuarioEgresado(Apl.ID_Egresado.Value);
                }
                else if (Apl.ID_Estudiante.HasValue)
                {
                    Aplicante = new UsuarioEstudiante(Apl.ID_Estudiante.Value);
                }

                return Aplicante;
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("Error en la base de datos. Intente en unos minutos" + SqlEx.Message);
            }
        }

        public void AplicarAVacante(int VacanteID, string ComentarioDeAplicacion)
        {
            try
            {
                Aplicacion AplicacionToSubmit = new Aplicacion(VacanteID, this, ComentarioDeAplicacion);
                AplicacionToSubmit.Insertar();

                this.aplicaciones = null;
            }
            catch (Exception Ex)
            {
                throw new Exception("Esta aplicacion ya existe\n" + Ex.Message);
            }
        }
        public void DesactivarAplicacion(int AplicacionID)
        {
            try
            {
                Aplicacion AplicacionToDeactivate = (from atd in this.Aplicaciones
                                                     where atd.ID == AplicacionID
                                                     select atd).First();

                AplicacionToDeactivate.ToggleActivation();
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("No existe tal aplicacion\n" + SqlEx.Message);
            }
        }
        public void ActivarAplicacion(int AplicacionID)
        {
            try
            {
                Aplicacion AplicacionToActivate = (from atd in this.Aplicaciones
                                                   where atd.ID == AplicacionID
                                                   select atd).First();

                if (AplicacionToActivate.VacanteAplicada.SiActiva)
                {
                    AplicacionToActivate.ToggleActivation();
                    return;
                }
                else
                {
                    throw new Exception("Esta aplicacion no se puede activar porque la vacante a la que estaba asociada ya no existe");
                }
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("No existe tal aplicacion\n" + SqlEx.Message);
            }
        }
        public void CambiarPassWord(string NewPassWord)
        {
            this.passWord = NewPassWord;

            this.Actualizar();
        }

        public void AgregarContacto(int TipoContactoID, string ContactoDescripcion)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();
                DataContextClasses.Contacto ContactoToAdd = new DataContextClasses.Contacto();

                ContactoToAdd.ID_TipoContacto = TipoContactoID;
                ContactoToAdd.ID_Usuario = this.id;
                ContactoToAdd.Contacto1 = ContactoDescripcion;

                if (this is UsuarioEgresado)
                {
                    ContactoToAdd.TipoUsuario = "Egresado";
                }
                else if (this is UsuarioEstudiante)
                {
                    ContactoToAdd.TipoUsuario = "Estudiante";
                }

                DB.Contactos.InsertOnSubmit(ContactoToAdd);
                DB.SubmitChanges();

                this.contactos = null;
            }
            catch (SqlException)
            {
                throw new Exception("Este contacto no se puede agregar, ya existe en la base de datos");
            }
        }
        public void AgregarContacto(string TipoContactoDescripcion, string ContactoDescripcion)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();
                DataContextClasses.Contacto ContactoToAdd = new DataContextClasses.Contacto();

                ContactoToAdd.ID_TipoContacto = (from tc in DB.TiposContactos
                                                 where tc.Descripcion == TipoContactoDescripcion
                                                 select tc).First().ID;

                ContactoToAdd.ID_Usuario = this.id;
                ContactoToAdd.Contacto1 = ContactoDescripcion;

                if (this is UsuarioEgresado)
                {
                    ContactoToAdd.TipoUsuario = "Egresado";
                }
                else if (this is UsuarioEstudiante)
                {
                    ContactoToAdd.TipoUsuario = "Estudiante";
                }

                DB.Contactos.InsertOnSubmit(ContactoToAdd);
                DB.SubmitChanges();

                this.contactos = null;
            }
            catch (SqlException)
            {
                throw new Exception("Este contacto no se puede agregar, puede que ya exista en la base de datos");
            }
        }
        public void ModificarContacto(int ContactoID, string ContactoDescripcion)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();

                DataContextClasses.Contacto ContactoToUpdate = (from ctu in DB.Contactos
                                                                where ctu.ID == ContactoID
                                                                select ctu).First();

                ContactoToUpdate.Contacto1 = ContactoDescripcion;

                DB.SubmitChanges();

                this.contactos = null;
            }
            catch (SqlException)
            {
                throw new Exception("Hubo un problema con la base de datos");
            }
        }
        public void EliminarContacto(int ContactoID)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();

                DataContextClasses.Contacto ContactoToDelete = (from c in DB.Contactos
                                                                where c.ID == ContactoID
                                                                select c).First();

                DB.Contactos.DeleteOnSubmit(ContactoToDelete);
                DB.SubmitChanges();

                this.contactos = null;
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("Error en la base de datos. Intente en unos minutos" + SqlEx.Message);
            }
        }

        public abstract void Actualizar();
        public abstract void AgregarHabilidad(int HabilidadID);
        public abstract void EliminarHabilidad(int HabilidadID);      
        #endregion   
    }
}